﻿using HomagChina.Basic.CCT.PLC;
using HomagGroup.Base.Communication.Items;
using HomagGroup.Base.Communication.Items.AdsProvider;
using HomagGroup.Base.Communication.Items.Config;
using System;
using System.ComponentModel;

namespace Proxy
{
    public class PlcHandle
    {
        public PlcHandle()
        {

        }

        public PlcHandle(string ProviderId, string Ip, int Port = 852)
        {
            SetUpProvider(ProviderId, Ip, Port);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="ProviderId">Stroage / Gantry / Panel Dividing / TPL / Edge Banding / Dividing Machine
        /// / TLB / Sorting Ling/ Packaging Line </param>
        /// <param name="Ip"></param>
        /// <param name="Port"></param>
        public void SetUpProvider(string ProviderId, string Ip, int Port = 852)
        {
            try
            {
                Globle.itemManagerConfig = new ItemManagerConfig();
                Globle.itemManagerConfig.Providers.Add(new AdsProviderConfig
                {
                    Id = ProviderId,
                    Port = Port,
                    AmsNetId = Ip,
                });
                Globle.itemManager = new ItemManager(Globle.itemManagerConfig, new AdsProviderFactory());

                VariabkeInit(ProviderId);
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="providerId"></param>
        /// <param name="varName"></param>
        /// <param name="autoUpdate"></param>
        /// <param name="updateRate"></param>
        /// <returns></returns>
        public Item SetUpItem(string providerId, string varName, bool autoUpdate = true, int updateRate = 50)
        {
            try
            {
                //Address address, bool autoUpdate = false, int updateRateInMilliseconds = 0, bool autoConnectAttempt = false
                var item = new Item(new Address(providerId, varName), autoUpdate, updateRate);
                item.Connect(Globle.itemManager);
                return item;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        private void VariabkeInit(string providerId)
        {
            PlcItems.Item_System_OperationMode = SetUpItem(providerId, PlcItems.Var_System_OperationMode);
            PlcItems.Item_System_InfeedButton = SetUpItem(providerId, PlcItems.Var_System_InfeedButton);

            Wholesale.Item_AIF_CT015_OrderState = SetUpItem(providerId, Wholesale.Var_AIF_CT015_OrderState);
            Wholesale.Item_AIF_CT015_Reference = SetUpItem(providerId, Wholesale.Var_AIF_CT015_Reference);
            Wholesale.Item_AIF_CT015_Direction = SetUpItem(providerId, Wholesale.Var_AIF_CT015_Direction);

            Wholesale.Item_MIF_BC010_OrderState = SetUpItem(providerId, Wholesale.Var_MIF_BC010_OrderState);
            Wholesale.Item_MIF_BC010_Reference = SetUpItem(providerId, Wholesale.Var_MIF_BC010_Reference);
            Wholesale.Item_MIF_BC010_Direction = SetUpItem(providerId, Wholesale.Var_MIF_BC010_Direction);

            Wholesale.Item_MO1_H330L_OrderState = SetUpItem(providerId, Wholesale.Var_MO1_H330L_OrderState);
            Wholesale.Item_MO1_H330L_Reference = SetUpItem(providerId, Wholesale.Var_MO1_H330L_Reference);
            Wholesale.Item_MO1_H330L_Direction = SetUpItem(providerId, Wholesale.Var_MO1_H330L_Direction);

            Wholesale.Item_MO1_H330R_OrderState = SetUpItem(providerId, Wholesale.Var_MO1_H330R_OrderState);
            Wholesale.Item_MO1_H330R_Reference = SetUpItem(providerId, Wholesale.Var_MO1_H330R_Reference);
            Wholesale.Item_MO1_H330R_Direction = SetUpItem(providerId, Wholesale.Var_MO1_H330R_Direction);

            Wholesale.Item_AOF_CT020_OrderState = SetUpItem(providerId, Wholesale.Var_AOF_CT020_OrderState);
            Wholesale.Item_AOF_CT020_Reference = SetUpItem(providerId, Wholesale.Var_AOF_CT020_Reference);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        [Description("Plc Read")]
        public object Read(Item item, string Type)
        {
            object readResult = null;
            try
            {
                if (!item.Connected)
                {
                    //连接
                    if (item.Connect(Globle.itemManager).HasError)
                    {
                        item.Connect(Globle.itemManager);
                    }
                }

                switch (Type)
                {
                    case "String":
                        readResult = item.ReadAsync().Result.Value == null
                             ? "" : item.ReadAsync().Result.Value;
                        break;

                    case "Int":
                        readResult = item.ReadAsync().Result.Value == null
                             ? -1 : item.ReadAsync().Result.Value;
                        break;

                    case "Bool":
                        readResult = item.ReadAsync().Result.Value == null
                             ? false : item.ReadAsync().Result.Value;
                        break;

                    default:
                        break;
                }

                return readResult;
            }
            catch (Exception ex)
            {
                switch (Type)
                {
                    case "String":
                        readResult = "";
                        break;

                    case "Int":
                        readResult = -1;
                        break;

                    case "Bool":
                        readResult = false;
                        break;

                    default:
                        break;
                }
                return readResult;
            }
        }

        public ResultCode Write(Item item, object value)
        {
            try
            {
                //Start:
                if (!item.Connected)
                {
                    //连接
                    if (item.Connect(Globle.itemManager).HasError)
                    {
                        //连接发生错误
                        item.Connect(Globle.itemManager);
                    }
                }

                //写入
                var writeResult = item.WriteAsync(value);
                //判断结果是否存在异常
                if (writeResult.IsFaulted)
                {
                    //写入有异常
                    //goto Start;
                }

                return ResultCode.Success;
            }
            catch (Exception ex)
            {
                return ResultCode.UnknownFailure;
            }
        }

        public ResultCode WriteStructure(Item item, PlcStructure value)
        {
            try
            {
                return ResultCode.Success;
            }
            catch (Exception ex)
            {
                return ResultCode.UnknownFailure;
            }
        }
    }
}